import { Request, Response } from 'express';
import z from 'zod';

// Zod 验证中间件生成器
const validateSchema = (schema: z.ZodSchema<any>) => {
    return (req: Request, res: Response, next: Function) => {
        try {
            const result = schema.parse({
                body: req.body,
                params: req.params,
                query: req.query,
            });

            if (result.body) req.body = result.body;


            next();
        } catch (error) {
            if (error instanceof z.ZodError) {
                // 格式化错误信息，提供更详细的验证失败信息
                const validationErrors = error.errors.map(err => {
                    const fieldPath = err.path.join('.');
                    const fieldName = err.path[err.path.length - 1];
                    const location = err.path[0]; // body, params, query

                    // 中文化字段名称映射
                    const fieldNameMap: Record<string, string> = {
                        'params.provider': 'OAuth 提供商',
                        'query.action': '操作类型',
                        'query.userId': '用户ID',
                        'query.code': '授权码',
                        'query.state': '状态参数',
                        'body.email': '邮箱',
                        'body.password': '密码',
                        'body.username': '用户名',
                        'body.oldPassword': '当前密码',
                        'body.newPassword': '新密码',
                        'body.resetCode': '重置验证码',
                        'body.refreshToken': '刷新令牌',
                    };

                    const friendlyFieldName = fieldNameMap[fieldPath] || fieldName;

                    // 位置中文化
                    const locationMap: Record<string, string> = {
                        'body': '请求体',
                        'params': 'URL路径参数',
                        'query': 'URL查询参数'
                    };

                    // 获取实际接收到的值
                    let actualValue: any = undefined;
                    try {
                        if (location === 'body') {
                            actualValue = req.body?.[fieldName];
                        } else if (location === 'params') {
                            actualValue = req.params?.[fieldName];
                        } else if (location === 'query') {
                            actualValue = req.query?.[fieldName];
                        }
                    } catch {
                        actualValue = undefined;
                    }

                    // 提供更友好的错误提示
                    let suggestion = '';
                    if (err.code === 'invalid_type') {
                        suggestion = `期望类型: ${err.expected}, 实际类型: ${err.received}`;
                    } else if (err.code === 'invalid_enum_value') {
                        suggestion = `允许的值: ${err.options?.join(', ')}`;
                    } else if (err.code === 'too_small') {
                        if (err.type === 'string') {
                            suggestion = `最少需要 ${err.minimum} 个字符`;
                        } else {
                            suggestion = `最小值: ${err.minimum}`;
                        }
                    } else if (err.code === 'too_big') {
                        if (err.type === 'string') {
                            suggestion = `最多允许 ${err.maximum} 个字符`;
                        } else {
                            suggestion = `最大值: ${err.maximum}`;
                        }
                    } else if (err.code === 'invalid_string') {
                        if (err.validation === 'email') {
                            suggestion = '请输入有效的邮箱地址格式';
                        } else if (err.validation === 'url') {
                            suggestion = '请输入有效的URL格式';
                        } else {
                            suggestion = `字符串格式验证失败: ${err.validation}`;
                        }
                    }

                    return {
                        field: fieldPath,
                        fieldName: friendlyFieldName,
                        location: locationMap[location] || location,
                        message: err.message,
                        code: err.code,
                        actualValue: actualValue,
                        suggestion: suggestion,
                        path: err.path
                    };
                });

                // 按位置分组错误
                const errorsByLocation = validationErrors.reduce((acc, error) => {
                    const location = error.path[0] as string;
                    if (!acc[location]) {
                        acc[location] = [];
                    }
                    acc[location].push(error);
                    return acc;
                }, {} as Record<string, any[]>);

                res.status(400).json({
                    success: false,
                    message: `参数验证失败，共 ${validationErrors.length} 个错误`,
                    errors: validationErrors,
                    errorsByLocation: errorsByLocation,
                    timestamp: new Date().toISOString(),
                    requestInfo: {
                        method: req.method,
                        url: req.url,
                        hasBody: !!req.body && Object.keys(req.body).length > 0,
                        hasParams: !!req.params && Object.keys(req.params).length > 0,
                        hasQuery: !!req.query && Object.keys(req.query).length > 0
                    }
                });
                return;
            }

            res.status(400).json({
                success: false,
                message: '参数验证失败',
                error: error instanceof Error ? error.message : '未知错误',
                timestamp: new Date().toISOString()
            });
        }
    };
};

export default validateSchema;